package com.gkzf.ai.module.crm.framework.annotations.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gkzf.ai.module.crm.framework.annotations.JsonKey;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
public class JsonParser {

    /**
     * 将JSON字符串解析成指定类型的对象
     * @param jsonString JSON字符串
     * @param clazz 目标对象的Class
     * @param <T> 目标对象的类型
     * @return 解析后的对象实例
     * @throws Exception 解析过程中可能出现的异常
     */
    public static <T> T parse(String jsonString, Class<T> clazz) throws Exception {
        // 1. 使用Jackson将JSON字符串解析为Map
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> jsonMap = objectMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {});

        // 2. 通过反射创建目标类的实例
        T instance = clazz.getDeclaredConstructor().newInstance();

        // 3. 遍历目标类的所有字段
        for (Field field : clazz.getDeclaredFields()) {
            // 4. 检查字段上是否存在 @JsonKey 注解
            if (field.isAnnotationPresent(JsonKey.class)) {
                // 5. 获取注解实例
                JsonKey annotation = field.getAnnotation(JsonKey.class);
                String jsonKey = annotation.value();

                // 6. 从Map中获取JSON键对应的值
                Object value = jsonMap.get(jsonKey);
                if (value != null) {

                    // 7. 设置字段可访问（即使是private的）
                    String setterName = "set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
                    try {
                        Method setter = clazz.getMethod(setterName, field.getType());
                        setter.invoke(instance, value);
                    } catch (NoSuchMethodException e) {
                        // 如果没有对应的setter方法，可以选择忽略或记录日志
                        log.info("没有对应的setter方法 key名称: {}", field.getName());
                    }
                }
            }
        }

        return instance;
    }



    /**
     * 解析JSON数组字符串，返回一个List<T>。
     * @param jsonArray JSON数组, e.g., "[{\"key\":\"value\"}, ...]"
     * @param clazz 目标对象的Class
     * @return 解析后的对象列表
     */

    @SneakyThrows
    public static <T> List<T> parseArray(JSONArray jsonArray, Class<T> clazz){
        // 1. 将字符串解析为JSONArray
        if (jsonArray == null) {
            return new ArrayList<>(); // 或者抛出异常，取决于你的业务需求
        }

        List<T> resultList = new ArrayList<>(jsonArray.size());

        // 2. 遍历JSONArray
        for (Object item : jsonArray) {
            if (item instanceof JSONObject jsonObject) {
                // 3. 对数组中的每个JSONObject，调用私有辅助方法进行解析
                T instance = parseObject(jsonObject, clazz);
                log.info("转换对应对象结构：{}", instance);
                resultList.add(instance);
            }
            // 你可以在这里添加对其他类型（如String、Integer）的处理逻辑
        }
        return resultList;
    }

    /**
     * (核心逻辑) 将一个JSONObject对象根据注解映射到一个Java对象。
     * 这是被`parse`和`parseArray`复用的辅助方法。
     * @param jsonObject Fastjson的JSONObject
     * @param clazz 目标对象的Class
     * @return 解析后的对象实例
     */
    private static <T> T parseObject(JSONObject jsonObject, Class<T> clazz) throws Exception {
        T instance = clazz.getDeclaredConstructor().newInstance();

        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(JsonKey.class)) {
                JsonKey annotation = field.getAnnotation(JsonKey.class);
                String jsonKey = annotation.value();

                if (jsonObject.containsKey(jsonKey)) {
                    Object value = getTypedValue(jsonObject, jsonKey, field.getType());
                    if (value != null) {
                        String setterName = "set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
                        try {
                            Method setter = clazz.getMethod(setterName, field.getType());
                            setter.invoke(instance, value);
                        } catch (NoSuchMethodException e) {
                            // 如果没有对应的setter方法，可以选择忽略或记录日志
                            log.info("没有对应的setter方法 key名称: {}", field.getName());
                        }
                    }
                }
            }
        }
        return instance;
    }

    /**
     * 根据字段类型，从JSONObject获取强类型的值。
     * (此方法与之前版本相同，保持不变)
     */
    private static Object getTypedValue(JSONObject jsonObject, String key, Class<?> type) {
        if (type == String.class) {
            return jsonObject.getString(key);
        } else if (type == int.class || type == Integer.class) {
            return jsonObject.getInteger(key);
        } else if (type == long.class || type == Long.class) {
            return jsonObject.getLong(key);
        } else if (type == double.class || type == Double.class) {
            return jsonObject.getDouble(key);
        } else if (type == boolean.class || type == Boolean.class) {
            return jsonObject.getBoolean(key);
        } else if (type == java.util.Date.class) {
            return jsonObject.getDate(key);
        } else if (type == java.math.BigDecimal.class) {
        return jsonObject.getBigDecimal(key);
        }
        return jsonObject.get(key);
    }

}
